<template>
  <div class="honexun-multiple-select">
    <div :class="{ 'honexun-select': true, 'honexun-select-active': isSelect }" @click="honexunTap">
      <span class="show-info-each" v-for="(item, i) in showInfoList" :key="'showInfoList' + i">
        <span class="show-title">
          {{item.name}}
          <span v-show="item.childrenLength > 0">+{{item.childrenLength}}</span>
        </span>
      </span>
      <div :class="{'right-icon': true, 'is-active': isSelect}">
        <a-icon type="down"/>
      </div>
    </div>
    <div :class="{'honexun-select-content': true, 'honexun-has-data': list.length > 0}" @click="honexunContentTap"
         v-show="isSelect">
      <div class="each-select-line">
        <div class="each-row" @click="allTap">
          <div class="left">
            <a-checkbox :checked="selectAll" @change="selectAllChage">{{allTitle}}</a-checkbox>
          </div>
        </div>
        <div :class="{'each-row': true, 'is-active': parentIndex === i}" v-for="(item, i) in firstList"
             :key="'multi-parent' + i" @click="parentTab(i)">
          <div class="left">
            <a-checkbox :checked="item.isChecked" :indeterminate="item.indeterminate"
                        @change="parentChange(i)"></a-checkbox>
            <span>{{item.label}}</span>
          </div>
          <div class="right" v-show="!item.isLeaf">
            <a-icon type="right" v-show="!item.isLoading"/>
            <a-icon type="reload" spin v-show="item.isLoading"/>
          </div>
        </div>
      </div>
      <div class="each-select-line">
        <div class="each-row" v-for="(item, i) in nextLevelList" :key="'multi-child' + i">
          <div class="left">
            <a-checkbox :checked="item.isChecked" @change="nextLevelChange(i)">{{item.label}}</a-checkbox>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        // 是否全选
        selectAll: false,
        // 是否展示下面的数据
        isSelect: false,
        // 展示数据 provinceCode provinceName cityCodes
        showInfoList: [],
        // 第一级列表数据
        firstList: [],
        // 当前二级的所属父级
        parentIndex: null,
        // 二级展示的数据
        nextLevelList: [],
        // 是否是tap事件
        isTap: false,
        // 是否刷新勾选状态
        needRefreshSelect: true
      }
    },
    mounted() {
      document.addEventListener('click', this.closeSelectContent);
    },
    beforeDestroy() {
      document.removeEventListener('click', this.closeSelectContent);
    },
    methods: {
      // 全选行点击
      allTap() {
        this.nextLevelList = [];
        this.parentIndex = -1;
      },
      // 全选点击事件
      selectAllChage(e) {
        this.selectAll = e.target.checked;
        let list = JSON.parse(JSON.stringify(this.list));
        for (let item of list) {
          item.isChecked = this.selectAll;
          item.indeterminate = false;
          if (item.children) {
            for (let el of item.children) {
              el.isChecked = this.selectAll;
            }
          }
        }
        if (this.selectAll) {
          this.setAllSelect();
        } else {
          this.clearSelect();
        }
        this.$emit('update:list', list);
      },
      // 清空选择
      clearSelect() {
        this.$emit('changeValue', []);
        this.showInfoList = [];
      },
      // 判断是否是全选
      judgeAllSelect(list) {
        let selectAll = true;
        for (let item of list) {
          if (!item.isChecked) {
            selectAll = false;
            break;
          }
        }
        this.selectAll = selectAll;
        if (selectAll) {
          this.setAllSelect();
        } else {
          this.setShowList(list);
        }
      },
      // 设置全选展示
      setAllSelect() {
        let val = [{
          provinceCode: -1,
          provinceName: this.allTitle,
          cityCodes: '',
          hasAllCity: true
        }];
        this.needRefreshSelect = false;
        this.$emit('changeValue', val);
      },
      // 设置展示的数据
      setShowList(list) {
        let array = [];
        for (let i = 0; i < list.length; i++) {
          let item = list[i];
          if (item.isChecked || item.indeterminate) {
            let cityCodes = '', codesArray = [];
            if (item.children) {
              if (item.children.length > 0) {
                for (let el of item.children) {
                  if (el.isChecked) {
                    codesArray.push(el.code);
                  }
                }
                cityCodes = codesArray.join(',');
              }
              array.push({
                provinceCode: item.code,
                provinceName: item.name,
                cityCodes: cityCodes,
                hasAllCity: item.isChecked
              })
            } else {
              this.needRefreshSelect = false;
              this.$emit('changeValue', array);
              this.getChildAndSet(i, this.setShowList);
              return;
            }
          }
        }
        this.needRefreshSelect = false;
        this.$emit('changeValue', array);
      },
      // 获取未有子集的数据
      getChildAndSet(i, fn) {
        this.$emit('child', {
          i, fn: ({result}) => {
            let list = this.setNextListUnShow({result, i});
            if (fn) fn(list);
          }
        });
      },
      // 父级点击选中事件
      parentChange(i) {
        let list = JSON.parse(JSON.stringify(this.list));
        list[i].isChecked = !list[i].isChecked;
        list[i].indeterminate = false;
        if (list[i].children) {
          for (let item of list[i].children) {
            item.isChecked = list[i].isChecked;
          }
          this.nextLevelList = list[i].children;
        }
        this.$emit('update:list', list);
        this.judgeAllSelect(list);
      },
      // 二级点击事件
      nextLevelChange(i) {
        let list = JSON.parse(JSON.stringify(this.list));
        list[this.parentIndex].children[i].isChecked = !list[this.parentIndex].children[i].isChecked;
        let isChecked = true, indeterminate = false;
        for (let item of list[this.parentIndex].children) {
          if (!item.isChecked) {
            isChecked = false;
          } else {
            indeterminate = true;
          }
        }
        if (isChecked) indeterminate = false;
        list[this.parentIndex].isChecked = isChecked;
        list[this.parentIndex].indeterminate = indeterminate;
        this.nextLevelList = list[this.parentIndex].children;
        this.$emit('update:list', list);
        this.judgeAllSelect(list);
      },
      // 关闭弹窗事件
      closeSelectContent() {
        this.isSelect = false;
      },
      // 框的点击事件
      honexunTap(e) {
        e.stopPropagation();
        this.isSelect = !this.isSelect;
      },
      // 内容区域点击
      honexunContentTap(e) {
        e.stopPropagation();
      },
      // 父级点击事件
      parentTab(i) {
        if (this.parentIndex === i) return;
        this.parentIndex = i;
        let now = this.list[i];
        if (!now.children) {
          let list = JSON.parse(JSON.stringify(this.list));
          list[i].isLoading = true;
          this.$emit('update:list', list);
          this.$emit('child', {i, fn: this.setNextList});
        } else {
          this.nextLevelList = now.children;
        }
      },
      // 设置下一级但不显示下一级
      setNextListUnShow({result, i}) {
        let list = JSON.parse(JSON.stringify(this.list));
        this.$set(list[i], 'isLoading', false);
        this.$set(list[i], 'children', result);
        if (result.length === 0) {
          this.$set(list[i], 'isLeaf', true);
        }
        if (list[i].indeterminate) {
          let cityCodes = '';
          for (let el of this.value) {
            if (el.provinceCode === list[i].code) {
              cityCodes = el.cityCodes;
            }
          }
          for (let item of result) {
            item.isChecked = cityCodes.indexOf(item.code) > -1;
          }
        } else {
          for (let item of result) {
            item.isChecked = list[i].isChecked;
          }
        }
        this.$emit('update:list', list);
        return list;
      },
      // 设置下一级数据
      setNextList({result, i}) {
        this.setNextListUnShow({result, i});
        this.nextLevelList = result;
      },
      // 设置数据回显
      initSelect(val) {
        if (val.length === 0) {
          this.batchSet(false);
        } else {
          if (val.length === 1 && val[0].provinceCode === -1) {
            this.batchSet(true);
          } else {
            this.setSelect(val);
          }
        }
      },
      // 设置回显
      setSelect(val) {
        let list = JSON.parse(JSON.stringify(this.list));
        for (let item of val) {
          for (let el of list) {
            if (el.code === item.provinceCode) {
              el.isChecked = item.hasAllCity;
              el.indeterminate = !item.hasAllCity;
              if (el.children && el.children.length > 0) {
                for (let sub of el.children) {
                  if (item.cityCodes.indexOf(sub.code) > -1) {
                    sub.isChecked = true;
                  }
                }
              }
              break;
            }
          }
        }
        this.$emit('update:list', list);

      },
      // 批量设置选中或未选中
      batchSet(val) {
        let list = JSON.parse(JSON.stringify(this.list));
        for (let item of list) {
          item.isChecked = val;
          item.indeterminate = false;
          if (item.children && item.children.length > 0) {
            for (let el of item.children) {
              el.isChecked = val;
            }
          }
        }
        this.$emit('update:list', list);
      }
    },
    props: {
      // 列表数据
      list: {
        type: Array,
        default() {
          return []
        }
      },
      // 选中的值
      value: {
        type: Array,
        default() {
          return []
        }
      },
      allTitle: {
        type: String,
        default() {
          return '全国'
        }
      }
    },
    watch: {
      list(newVal, oldVal) {
        this.firstList = newVal;
        if (oldVal.length === 0) {
          this.initSelect(this.value);
        }
      },
      value(newVal) {
        this.showInfoList = [];
        for (let item of newVal) {
          let obj = {
            name: item.provinceName,
            childrenLength: item.cityCodes ? item.cityCodes.split(',').length : 0
          };
          this.showInfoList.push(obj);
        }
        if (!this.needRefreshSelect) {
          this.needRefreshSelect = true;
        } else {
          this.initSelect(newVal);
        }
        console.log(JSON.stringify(newVal));
      }
    },
    model: {
      prop: 'value',
      event: 'changeValue'
    }
  }
</script>

<style lang="less" scoped>
  .honexun-multiple-select {
    position: relative;
    padding: 4px 0;

    .honexun-select {
      width: 100%;
      height: 32px;
      border: 1px solid #d9d9d9;
      border-radius: 3px;
      padding: 0 24px 0 11px;
      cursor: pointer;
      -webkit-transition: border-color 0.4s;
      -moz-transition: border-color 0.4s;
      -ms-transition: border-color 0.4s;
      -o-transition: border-color 0.4s;
      transition: border-color 0.4s;
      .textOverflow();
      position: relative;

      .right-icon {
        position: absolute;
        z-index: 2;
        height: 30px;
        top: 0;
        right: 10px;
        vertical-align: top;
        line-height: 30px;
        transition: transform 0.3s;

        &.is-active {
          -webkit-transform: rotate(180deg);
          -moz-transform: rotate(180deg);
          -ms-transform: rotate(180deg);
          -o-transform: rotate(180deg);
          transform: rotate(180deg);
        }
      }

      &:hover {
        border-color: @activeRed;
      }

      &.honexun-select-active {
        border-color: rgba(215, 55, 55, 0.7);
        -webkit-box-shadow: 0 0 3px @activeRed;
        -moz-box-shadow: 0 0 3px @activeRed;
        box-shadow: 0 0 3px @activeRed;
      }

      .show-info-each {
        font-size: 12px;
        height: 30px;
        line-height: 30px;
        vertical-align: top;

        .commonStyle() {
          line-height: 22px;
          background: #f1f1f1;
          color: @colorCommonFont;
          display: inline-block;
          padding: 0 6px;
          -webkit-border-radius: 3px;
          -moz-border-radius: 3px;
          border-radius: 3px;
          margin: 0 8px 0 0;
        }

        .show-title {
          .commonStyle();
        }

        .show-num {
          .commonStyle();
        }
      }
    }

    .honexun-select-content {
      position: absolute;
      z-index: 10;
      top: 38px;
      height: 95px;
      display: flex;
      width: 100%;
      background: #ffffff;
      border: 1px solid #ECECEC;
      -webkit-box-shadow: 0 0 5px 0 #ECECEC;
      -moz-box-shadow: 0 0 5px 0 #ECECEC;
      box-shadow: 0 0 5px 0 #ECECEC;
      -webkit-border-radius: 3px;
      -moz-border-radius: 3px;
      border-radius: 3px;

      &.honexun-has-data {
        height: 200px;
      }

      .each-select-line {
        flex: 1;
        height: 100%;
        overflow-y: auto;

        .each-row {
          width: 100%;
          height: 32px;
          line-height: 32px;
          display: flex;
          align-items: center;
          justify-content: space-between;
          font-size: 14px;
          padding: 0 8px;
          cursor: pointer;
          .textOverflow();

          &:hover {
            background: @greyBackground;
          }

          &.is-active {
            background: @greyBackground;
          }

          .left {
            font-size: 12px;

            span {
              display: inline-block;
              margin-left: 8px;
            }
          }
        }
      }
    }

  }
</style>
